import java.util.*;

public class Solution770 {

    int cur=0;

    public List<String> basicCalculatorIV(String expression, String[] evalvars, int[] evalints) {
        Map<String,Integer> map=new HashMap<>();
        for (int i=0;i<evalvars.length;i++){
            map.put(evalvars[i],evalints[i]);
        }
        Map<List<String>,Integer> target=dfs(expression,map);
        if (target.size()==0){
            return Collections.singletonList("0");
        }
        List<String> ans=new ArrayList<>();
        List<Map.Entry<List<String>,Integer>> list=new ArrayList<>(target.entrySet());
        list.sort((a,b)->{
            if (a.getKey().size()!=b.getKey().size()){
                return b.getKey().size()-a.getKey().size();
            }
            List<String> c=new ArrayList<>(a.getKey());
            List<String> d=new ArrayList<>(b.getKey());
            c.sort(Comparator.naturalOrder());
            d.sort(Comparator.naturalOrder());
            for (int i=0;i<c.size();i++){
                if (!c.get(i).equals(d.get(i))){
                    return c.get(i).compareTo(d.get(i));
                }
            }
            return 0;
        });
        for (Map.Entry<List<String>, Integer> entry : list) {
            StringBuilder stringBuilder=new StringBuilder();
            stringBuilder.append(entry.getValue());
            List<String> c=new ArrayList<>(entry.getKey());
            c.sort(Comparator.naturalOrder());
            for (String s : c) {
                stringBuilder.append("*");
                stringBuilder.append(s);
            }
            ans.add(stringBuilder.toString());
        }
        return ans;
    }

    private Map<List<String>, Integer> dfs(String expression, Map<String, Integer> map) {
        Stack<Map<List<String>,Integer>> stack=new Stack<>();
        Stack<Character> stack2=new Stack<>();
        while (cur<expression.length() && expression.charAt(cur)!=')'){
            if (expression.charAt(cur)>='0' && expression.charAt(cur)<='9'){
                StringBuilder stringBuilder=new StringBuilder();
                while (cur<expression.length() && expression.charAt(cur)>='0' && expression.charAt(cur)<='9'){
                    stringBuilder.append(expression.charAt(cur));
                    cur++;
                }
                int o=Integer.parseInt(stringBuilder.toString());
                Map<List<String>,Integer> map2=new HashMap<>();
                map2.put(new ArrayList<>(),o);
                stack.push(map2);
            }else if (expression.charAt(cur)>='a' && expression.charAt(cur)<='z'){
                StringBuilder stringBuilder=new StringBuilder();
                while (cur<expression.length() && expression.charAt(cur)>='a' && expression.charAt(cur)<='z'){
                    stringBuilder.append(expression.charAt(cur));
                    cur++;
                }
                String o=stringBuilder.toString();
                Map<List<String>,Integer> map2=new HashMap<>();
                if (map.containsKey(o)){
                    map2.put(new ArrayList<>(),map.get(o));
                }else{
                    map2.put(Collections.singletonList(o),1);
                }
                stack.push(map2);
            }else if (expression.charAt(cur)==' '){
                cur++;
            }else if (expression.charAt(cur)=='('){
                cur++;
                stack.push(dfs(expression,map));
            }else {
                stack2.push(expression.charAt(cur));
                cur++;
            }
        }
        cur++;
        Stack<Map<List<String>,Integer>> newStack=new Stack<>();
        Stack<Character> newStack2=new Stack<>();
        newStack.push(stack.get(0));
        for (int i=1;i<stack.size();i++){
            if (stack2.get(i-1)=='*'){
                newStack.push(mul(newStack.pop(),stack.get(i)));
            }else {
                newStack.push(stack.get(i));
                newStack2.push(stack2.get(i-1));
            }
        }
        Map<List<String>,Integer> ans=newStack.get(0);
        for (int i=1;i<newStack.size();i++){
            if (newStack2.get(i-1)=='+'){
                ans=add(ans,newStack.get(i),1);
            }else {
                ans=add(ans,newStack.get(i),-1);
            }
        }
        Map<List<String>,Integer> m=new HashMap<>();
        m.put(new ArrayList<>(),1);
        ans=mul(ans,m);
        return ans;
    }

    private Map<List<String>, Integer> mul(Map<List<String>, Integer> a, Map<List<String>, Integer> b) {
        Map<List<String>,Integer> map=new HashMap<>();
        for (Map.Entry<List<String>, Integer> e1 : a.entrySet()) {
            for (Map.Entry<List<String>, Integer> e2 : b.entrySet()) {
                List<String> list=new ArrayList<>(e1.getKey());
                list.addAll(e2.getKey());
                list.sort(Comparator.naturalOrder());
                map.put(list,map.getOrDefault(list,0)+e1.getValue()*e2.getValue());
                if (map.get(list)==0){
                    map.remove(list);
                }
            }
        }
        return map;
    }

    private Map<List<String>, Integer> add(Map<List<String>, Integer> a, Map<List<String>, Integer> b,int tie) {
        Map<List<String>,Integer> map=new HashMap<>(a);
        for (Map.Entry<List<String>, Integer> entry : b.entrySet()) {
            map.put(entry.getKey(),map.getOrDefault(entry.getKey(),0)+entry.getValue()*tie);
            if (map.get(entry.getKey())==0){
                map.remove(entry.getKey());
            }
        }
        return map;
    }

    public static void main(String[] args) {
        System.out.println(new Solution770().basicCalculatorIV("a * b * c + b * a * c * 4",new String[]{},new int[]{}));
    }
}
